BackForward

/*----------------------------------------\
|Fill up the table or a bookmark, this funciton is the combination   |
|   of %filltable, %write and %updatebmark; so an oldbmark is given, |
|   it will update the contents of the bookmarked area, if a newbmark|
|   is given, it will create a bookmark for the contents of the      |
|   variables from a data set. If neither an oldbmark or a newbmark  |
|   is given, it will write under the current cursor.                |
|Note:                                                               |
|    if you specified the DLM is CELL, then it will assume you are   |
|   dealing with a table then it won't update bookmark. Also, you    |
|   can't expect the function to update a bookmark or create a       |
|   bookmark when you want the line to be centered or leftindented   |
|   in the word document.                                            |
|Important Notice:                                                   |
|   1. Updating a bookmark or creating a new bookmark: the function  |
|     must be using in open code; you can't use this function within |
|     a data step, however, you can specify "indata" to input a data |
|     set.   It has a similar performance like %updatebmark();       |
|  2. Fill a table: the function can be used within a data step or as|
|     a open code if used in open code, you must give it an input    |
|     data set "indata"; you can not fill a table and create bookmark|
|     concurrently. You must not give it a bookmark if you specify   |
|      the dlm=cell. It has a similar performance like %labeltable();|
|  3. The function can be used outside a data step and without given |
|      an input data set, it has a performance like %write() and     |
|     %labeltable();                                                 |
|  4. Difference between this function and %filltable:               |
|      a) %filltable can't update a bookmark, this function can;     |
|     b) %filltable can't write sentence (quoted text strings), but  |
|        this function can; %filltable can't create labels,          |
|        this function can;                                          |
|     c) When you use %filltable, it will generate a new delimiter   |
|        before it fill in a variable or "text"; this function will  |
|        fill in a variable then generate a new delimiter, delimiter |
|        will include comma, semicolon, period, next cell, next para,|
|        paraoverwritten;                                            |
|  5. In summary, this function is a combination of %write(),        |
|     %updatebmark(), %labeltable(), %filltable(); any action you can|
|     accomplish with these functions, now you can do with %fillup.  |
|-------------------------------------------|
|--------------------------------------------------------------------|
|---------------------------|
|  var: the variables you want to fill in the next cell,             |
|       var=(a1, a2) / a1 ± a2;                                      |
|  Note: the var can be a quoted string, but if quoted, the function |
|        assumes it is a text, then it will write the text into the  |
|        cell.                                                       |
|  data: the dataset that contains the variables;                    |
|        if data set is given you can use it outside a data step;    |
|        but you can combine the function with a datastep, it will be|
|        more powerful;                                              |
|  nextdlm=F / T; Default is 'T';                                    |
|        T-- next delimiter; e.g. next cell if "dlm=cell";           |
|        F -- write under the current cursor without jumping to the  |
|          next dlm;                                                 |
|  format: how do you want to present your variables:                |
|          char--$n.m; numeric--n.m;                                 |
|          if you want more than one variables in a cell, you can use|
|          two different format: the 1st format for the 1st variable,|
|          the 2nd format for the 2nd variable;                      |
| justify: CENTER/center -- center justified;                        |
|          LEFT/left -- left justified;                              |
|          RIGHT/right -- right justified;                           |
| fontstyle: BOLD/bold -- boldface;                                  |
|          ITALIC/italic -- italic;                                  |
|          UNDERLINE/underline -- underline;                         |
|          ARIAL/Arial --Arial;                                      |
|          default REGULAR/regular -- regular, no special styles and |
|                font is "Times New Ramons";                         |
|          NOTE: this fontstyles can be used in together to display a|
|                special format styles;                              |
| Color: what color do you want the text be displayed;               |
|          By default, it will keep the current color;               |
| dbw: T/F -- add  a delimiter to the word document before writing   |
|          anything or not?                                          |
|          (True - insert a delimiter first;                         |
|           False - insert a delimiter after the writing;            |
| dlm: CELL/cell/NEXTCELL/nextcell -- put the cursor to the nextcell |
|          before executing this function;                           |
|      PARA/para/INSERTPARA/insertpara -- put the cursor to a newline|
|          before executing this  function;                          |
|      PARA OVERWRITTEN/para written -- put the cursor to a nextline |
|          overwritten the contents in the next line, used to update |
|          a table;                                                  |
|      COMMA/comma -- put a ', ' before execution of the function;   |
|      SPACE/space -- put a '¶' before execution of the function;    |
|      SEMICOLON/semicolon -- put a ';' after the execution;         |
|      PERIOD/period -- put a '.' after the execution;               |
|      INSERTROWABOVE -- Insert a row above the current row;         |
|      INSERTROWBELOW -- Insert a row below the current row;         |
| leftindent:default 0; often used value 0.25;                       |
| where  : Can be used only when an input dataset is given;          |
| wordref: word reference; not necessary default is "wordsys";       |
| NOTE: this function can be used in a data step, it will fill in    |
|       one cell per function per iteration in the currect datastep. |
|-----------------------------|
|--------------------------------------------------------------------|
|---------------------------------------|
|  Example:                                                          |
|  data _null_;                                                      |
|    set one;                                                        |
|    %fillup(var=(y +- x),format=4.0 4.0,fontstyle=TIMES);           |
|  run;                                                              |
|  The cell in the table will look like this (x ± y)                 |
| %fillup(oldbmark="sample1",newbmark="sample1",                     |
|         var="This is " x total cnt, indata=one,nextdlm=T,color=,   |
|         fontstyle=REGULAR TIMES, dlm=SPACE, wordref=wordsys);      |
\----------------------------------------*/
%macro fillup(oldbmark=, newbmark=&oldbmark, var=, format=, indata=,
              justify=center, dlm=CELL, color=, fontstyle=, nextdlm=T,
              dbw=F,fontsize=10,leftindent=0,where=,wordref=wordsys);
/*--------------------------------------------\
| Copy Right: Duo Zhou;                       |
| Created:  9-16-2001 9:46pm;                 |
| Modified: 1-15-2002 10:01pm;                |
| Purpose: update a bookmark or fill a table  |
\--------------------------------------------*/
%local nwords numi _j_ iblock nfmts currpos colorint qtemp tempvar;
%let tempvar=%qscan(&var,1,%str(''""));
%if (%index(&var,%str(%'))) %then %do;
   %let var=%sysfunc(tranwrd(&var,%str(%'),%str(%")));
%end;
%let dlm=%sysfunc(dequote(%quote(&dlm)));
%let hascolor=;
%if &color ne %then %do;
   %let hascolor =1;
   %let colorint=%colorint(&color);
%end;
%else %if (&hascolor=1)%then %do;
   %let colorint=&color_int;
%end;
%else %do;
   %let hascolor=0;
   %let colorint=0;
%end;

/****/
%local ntexts textcnt rtxt nvars myidx ibl tbl lbl lblock lvar ivar;
%let ntexts=1;
%let text1=%qscan(&var, &ntexts, %str(""));
%if (%length(&&text&ntexts)>0)%then %do;
   %if (&&text&ntexts ne) %then %do;
      %let textcnt=1; %let rtxt&textcnt=&&text&ntexts;
   %end;
   %else %do; %let textcnt=1; %end;
%end;
%else %do; %let textcnt=1; %end;
%do %while(%length(&&text&ntexts) gt 0);
   %let ntexts=%eval(&ntexts+1);
   %let text&ntexts=%qscan(&var, &ntexts, %str(""));/*%put text&ntexts is &&text&ntexts;*/
   %if (&&text&ntexts ne) %then %do;
      %let textcnt=%eval(&textcnt+1);%let rtxt&textcnt=&&text&ntexts;
   %end;
%end;
/****/
%let nwords=1; %let ibl=1; %let tbl=1;   %let lbl=1; %let block0=;
%do myidx=1 %to &textcnt;
   %if (%index(&var,"&&text&myidx") ) %then %do;
      %let lblock=&&text&myidx; %let ibl=%eval(&tbl-1);
      %if (%length(&&block&ibl) >0) %then %do;
         %let tbl=&ibl;
         %let block&tbl=&&block&tbl.&lblock;
      %end;
      %else %do;
         %let tbl=&ibl;
         %let block&tbl=&lblock;
      %end;
      %if (%eval(%index(&var,"&&text&myidx")+%length("&&text&myidx"))<%length(&var)) %then %do;
         %let var=%substr(&var, %eval(%index(&var,"&&text&myidx")+%length("&&text&myidx")),
                     %eval(%eval(%length(&var)+1)-%eval(%index(&var,"&&text&myidx")+%length("&&text&myidx"))));
      %end;
      %if (&myidx = &textcnt) %then %do;
         %let block&tbl="&&block&tbl";
      %end;
   %end;
   %else %do;
      %let nvars=1;
      %let var&nwords=%qscan(&&text&myidx, &nvars, %str( (){}[]+,-/\%:><±*^°$#@~=|));
      %do %while(%length(&&var&nwords) gt 0);
         %let nwords=%eval(&nwords+1);
         %let nvars=%eval(&nvars+1);
         %let var&nwords=%qscan(&&text&myidx, &nvars, %str( (){}[]+,-/\%:><±*^°$#@~=|));
      %end;
      %let nvars=%eval(&nvars-1);
      /***** subblock ****/
      %let lvar=%eval(&nwords-&nvars);
      %if (%index(&&text&myidx,&&var&lvar)>1) %then %do;
         %let lblock=%substr(&&text&myidx,1,%eval(%index(&&text&myidx,&&var&lvar)-1));
         %let currpos=%eval(%length(&&var&lvar)+%index(&&text&myidx,&&var&lvar));
      %end;
      %else %do;
         %let lblock=;
         %let currpos=%eval(%length(&&var&lvar)+1);
      %end;
      %let ibl=%eval(&tbl-1);
      %if (%length(&&block&ibl)>0) %then %do;
         %let tbl=&ibl;
         %let block&tbl="&&block&tbl.&lblock";
         %let tbl=%eval(&tbl+1);
      %end;
      %else %do;
         %let tbl=&ibl;
         %let block&tbl="&lblock";
         %let tbl=%eval(&tbl+1);
      %end;
      %do _j_=1 %to %eval(&nvars-1);
         %let ivar=%eval(&_j_+1);%let lvar=%eval(&lvar+1);
         %let block&tbl=
                  "%substr(&&text&myidx, &currpos,%eval(%index(&&text&myidx,&&var&lvar)- &currpos))";
         %let currpos=%eval(%index(&&text&myidx,&&var&lvar)+%length(&&var&lvar));
         %let tbl=%eval(&tbl+1);
      %end;
      %if (%length(&&text&myidx)>=&currpos) and (%length(&&text&myidx) > %eval(%index(&&text&myidx,&&var&nwords)+%length(&&var&nwords)-1))
         %then %do;
         %let block&tbl=
                  %substr(&&text&myidx,&currpos,
                       %eval(%length(&&text&myidx)-%index(&&text&myidx,&&var&lvar)-
                       %length(&&var&lvar)+1));
      %end;
      %else %do;
         %let block&tbl=;
      %end;
      %if (%quote(&myidx) = %quote(&textcnt)) %then %do;
         %let block&tbl="&&block&tbl";
      %end;
      %if (%length(&var)>=%eval(%index(&var,&&text&myidx)+%length(&&text&myidx))) %then %do;
         %let var=%substr(&var, %eval(%index(&var,&&text&myidx)+%length(&&text&myidx)),
                  %eval(%eval(%length(&var)+1)-%eval(%index(&var,&&text&myidx)+%length(&&text&myidx))));
      %end;
   %end;
   %let tbl=%eval(&tbl+1);
%end;
%let nwords=%eval(&nwords-1);
%let totblocks=&tbl;
/****/

/**** Used to find out the characters among the var names *****/
%do _k_=1 %to &nwords;
   %let format&_k_=%qscan(&format,&_k_,%str( ));
   %if (%quote(&&format&_k_) eq) %then %do;
       %let format&_k_= ;
   %end;
   %else %do;
      %if (not %index(&&format&_k_, .)) %then %do;
         %put ==> Alert! Check format&_k_: <&&format&_k_>, it may not be a valid format  or !;
         %goto finish;
      %end;
   %end;
%end;
%let _k_=0;
%if (%quote(&oldbmark) ne) %then %do;
   %let oldbookmark=%sysfunc(dequote(&oldbmark));
   %if (%quote(&newbmark) eq) %then %do;
   %let newbmark=&oldbmark;
   %end;
%end;
%if (%quote(&newbmark) ne) %then %do;
   %let newbookmark=%sysfunc(dequote(&newbmark));
%end;
%if (%index(%upcase(&dlm),CELL)) %then %do;
   %put --> Note:  You specified the dlm is "CELL", I suppose you want to fillin a table.;
%end;
%else %if (%index(%upcase(&dlm), OVERW)) and (%index(%upcase(&dlm),PARA) or %index(%upcase(&dlm),ENTER))%then %do;
   %put ==> Alert! You are about to overwrite the next line.;
%end;
%if (%index(&oldbmark, %str(%')) or %index(&oldbmark, %str(%")) or
     %index(&newbmark, %str(%')) or %index(&newbmark, %str(%"))) and
    (%quote(&indata) ne) %then %do;
   %put --> Note:  You are about to update a bookmark.;
   %if (%index(&oldbmark, %str(%')) or %index(&oldbmark, %str(%")) or
     %index(&newbmark, %str(%')) or %index(&newbmark, %str(%"))) and
    (%quote(&indata) ne) and (%index(%upcase(&dlm),CELL)) %then %do;
      %put --> Alert! About to updating a bookmark!;
      %goto finish;
   %end;
   data _null_;
      file &wordref lrecl=2000;
      length str $2000.;
      %if (%index(&oldbmark, %str(%'))) or (%index(&oldbmark, %str(%"))) %then %do;
      str='[EditGoTo .Destination = "'||trim(left("&oldbookmark"))||'"]';
      put str;
      %end;
      %if (%index(&newbmark, %str(%'))) or (%index(&newbmark, %str(%"))) %then %do;
      put '[Insert "¶"]';
      put '[CharLeft 1, 1]';
      str='[EditBookmark .Name = "'||trim(left("&newbookmark"))||'", .SortBy = 0, .Add]';
      put str;
      put '[CharLeft 1]';
      %end;
   run;
   %put --> Note:  Checking to see if input data set is valid! Please wait ... !;
   Data _null_;
   %if (%quote(&indata) ne) and (%sysfunc(exist(&indata))) %then %do;
        set &indata end=lastone;
   %end;
   %else %do;
      %put ==> Alert! Invalid data set name "&indata".;
   %end;
   %if (%quote(&where) ne) %then %do;
      where &where;
   %end;
%end;
%else %do;
   %if (%quote(&indata) ne) %then %do;
      Data _null_;
      %if (%upcase(&indata) ne _NULL_) and (%sysfunc(exist(&indata))) %then %do;
      set &indata end=lastone;
      %end;
      %if (%quote(&where) ne) %then %do;
      where &where;
      %end;
   %end;
%end;
   file &wordref lrecl=2000;
   length str $2000.;
   %if (%quote(%upcase(&dbw)) = %quote(T) or %quote(%upcase(&dbw)) eq %quote(TRUE)) %then %do;
      %if (%quote(%upcase(&nextdlm))= %quote(T) or %quote(%upcase(&nextdlm))= %quote(TRUE)) %then %do;
          %if (%index(%upcase(&dlm),CELL)) %then %do;
           put '[NextCell]';
         %end;
         %else %if (%index(%upcase(&dlm),PARA) or %index(%upcase(&dlm),ENTER)) %then %do;
              %if (%index(%upcase(&dlm), OVERW)) %then %do;
              put '[CharRight 1]';
              put '[EndOfLine 1]';
              %end;
              %else %do;
              put '[InsertPara]';
             %end;
         %end;
         %else %if (%index(%upcase(&dlm),SPACE)) %then %do;
         put '[Insert " "]';
         %end;
         %else %if (%index(%upcase(&dlm),COMMA)) %then %do;
         put '[Insert ", "]';
         %end;
         %else %if (%index(%upcase(&dlm),SEMI)) %then %do;
         put '[Insert "; "]';
         %end;
         %else %if (%index(%upcase(&dlm),PERIOD)) %then %do;
         put '[Insert ". "]';
         %end;
         %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&dlm))))), %quote(ROWBELOW))) %then %do;
             put '[TableInsertRowBelow .NumRows = ""]';
         %end;
         %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&dlm))))), %quote(ROWABOVE))) %then %do;
            put '[TableInsertRow .NumRows = ""]';
         %end;
         %else;
      %end;
   %end;
   %if (%index(%quote(%upcase(&dlm)),CELL)) %then %do;
      put '[TableSelectCell]';
   %end;
       str='[FormatFont .Points = "'||trim(left(put(&fontsize, 3.0)))||'"]';
   put str;
   %if (%index(%upcase(&fontstyle),TIME)) %then %do;
      str='[FormatFont .Font = "Times New Roman"]';
   put str;
   %end;
   %else %if (%index(%upcase(&fontstyle),ARIAL)) %then %do;
      str='[FormatFont .Font = "Arial"]';
   put str;
   %end;
   %else %if (%index(%upcase(&fontstyle),COURIER)) and not (%index(%upcase(&fontstyle),NEW))%then %do;
      str='[FormatFont .Font = "Courier"]';
   put str;
   %end;
   %else %if (%index(%upcase(&fontstyle),COURIER)) and (%index(%upcase(&fontstyle),NEW)) %then %do;
      str='[FormatFont .Font = "Courier New"]';
   put str;
   %end;
   %if (%index(%upcase(&fontstyle),REGULAR)) %then %do;
      str='[FormatFont  .Bold = 0 .Italic = 0 .Underline = 0]';
   put str;
   %end; 
   %else %do;
      %if (%index(%upcase(&fontstyle),BOLD)) %then %do;
          str='[FormatFont  .Bold = 1]';
      put str;
      %end;
      %if (%index(%upcase(&fontstyle),ITALIC)) %then %do;
         str='[FormatFont .Italic = 1]';
      put str;
      %end;
      %if (%index(%upcase(&fontstyle),UNDERLINE1)) %then %do;
           str='[FormatFont .Underline = 1]';
      put str;
      %end;
      %else %if (%index(%upcase(&fontstyle),UNDERLINE2)) %then %do;
           str='[FormatFont .Underline = 2]';
      put str;
      %end;
   %end;
   %if (%index(%upcase(&dlm),CELL)) or (%index(%upcase(&dlm),ROW))%then %do;
      %if (%upcase(&justify)=LEFT or %upcase(&justify)=L) %then %do;
      put '[LeftPara]';
      %end;
      %else %if (%upcase(&justify)=RIGHT or %upcase(&justify)=R) %then %do;
      put '[RightPara]';
      %end;
      %else %if (%upcase(&justify)=CENTER or %upcase(&justify)=C) %then %do;
      put '[CenterPara]';
      %end;
      %if &leftindent ne  %then %do;
         str= '[FormatParagraph .LeftIndent = "'||trim(left(put(&leftindent, 4.2)))||'" + Chr$(34)]';
      put str;
      %end;
      %else %do;
         str= '[FormatParagraph .LeftIndent = "0" + Chr$(34)]';
      put str;
      %end;
   %end;
   %if (%quote(&oldbmark) ne) and ((%quote(&indata) eq) or
       ((%quote(&indata) ne) and (not %index(&oldbmark, %str(%'))) and
        (not %index(&oldbmark, %str(%"))))) %then %do;
      str='[EditGoTo .Destination = "'||trim(left(&oldbmark))||'"]';
      put str;
   %end;
   %if (%quote(&newbmark) ne) and ((%quote(&indata) eq) or
       ((%quote(&indata) ne) and (not %index(&newbmark, %str(%'))) and
        (not %index(&newbmark, %str(%"))))) %then %do;
      put '[Insert "¶"]';
      put '[CharLeft 1, 1]';
      str='[EditBookmark .Name = "'||trim(left(&newbmark))||'", .SortBy = 0, .Add]';
      put str;
      put '[CharLeft 1]';
   %end;
   %if (%length(&block0) >2) %then %do;
      str='[Insert "'||&block0||'"]';
   put str;
   %end;
   %do _ij_=1 %to &nwords;
      %let iblock=&_ij_;
      %let mvar&_ij_=%qscan(&&var&_ij_,1,%str(''""));
      %if (%length(&&var&_ij_) > %length(&&mvar&_ij_)) %then %do;
           str='[Insert "'||"&&mvar&_ij_"||'"]';
        put str;
      %end;
      %else %do;
         %if &&format&_ij_ ne %then %do;
            str='[Insert "'||trimn(left(put(&&var&_ij_, &&format&_ij_)))||'"]';
         put str;
         %end;
         %else %do;
            str='[Insert "'||trimn(left(&&var&_ij_))||'"]';
         put str;
         %end;
      %end;
      %if (&iblock >= 1 ) and (&iblock <=&totblocks) %then %do;
         %let unblock&iblock=%qscan(&&block&iblock, 1, %str(""));
         %if (%index(%quote(&&unblock&iblock),%quote(+-))) %then %do;
            %let sub1block&iblock="%substr(&&unblock&iblock, 1, %eval(%index(&&unblock&iblock,+-)-1))";
            %let sub2block&iblock="%substr(&&unblock&iblock, %eval(%index(&&unblock&iblock,+-)+2),%eval(%length(&&unblock&iblock)-%index(&&unblock&iblock,+-)-1))";
               str= '[Insert "'||&&sub1block&iblock||'"]';
            put str;
               str= '[InsertSymbol .Font = "Symbol", .CharNum = "177"]';
            put str;
               str= '[Insert "'||&&sub2block&iblock||'"]';
            put str;
         %end;
         %else %if (%index(%quote(&&unblock&iblock),%quote(>=))) %then %do;
             %let sub1block&iblock="%substr(&&unblock&iblock, 1, %eval(%index(&&unblock&iblock,>=)-1))";
             %let sub2block&iblock="%substr(&&unblock&iblock, %eval(%index(&&unblock&iblock,>=)+2),%eval(%length(&&unblock&iblock)-%index(&&unblock&iblock,>=)-1))";
                 str= '[Insert "'||&&sub1block&iblock||'"]';
              put str;
               str= '[InsertSymbol .Font = "Symbol", .CharNum = "179"]';
              put str;
                 str= '[Insert "'||&&sub2block&iblock||'"]';
              put str;
         %end;
         %else %if (%index(%quote(&&unblock&iblock),%quote(<=))) %then %do;
             %let sub1block&iblock="%substr(&&unblock&iblock, 1, %eval(%index(&&unblock&iblock,<=)-1))";
             %let sub2block&iblock="%substr(&&unblock&iblock, %eval(%index(&&unblock&iblock,<=)+2),%eval(%length(&&unblock&iblock)-%index(&&unblock&iblock,<=)-1))";
                 str= '[Insert "'||&&sub1block&iblock||'"]';
              put str;
                 str= '[InsertSymbol .Font = "Symbol", .CharNum = "163"]';
              put str;
                 str= '[Insert "'||&&sub2block&iblock||'"]';
              put str;
         %end;
         %else %if (%index(%quote(&&unblock&iblock),%quote(*))) %then %do;
             %let sub1block&iblock="%substr(&&unblock&iblock, 1, %eval(%index(&&unblock&iblock,*)-1))";
             %let sub2block&iblock="%substr(&&unblock&iblock, %eval(%index(&&unblock&iblock,*)+1),%eval(%length(&&unblock&iblock)-%index(&&unblock&iblock,*)))";
                 str= '[Insert "'||&&sub1block&iblock||'"]';
              put str;
               str= '[InsertSymbol .Font = "Symbol", .CharNum = "180"]';
              put str;
                 str= '[Insert "'||&&sub2block&iblock||'"]';
              put str;
         %end;
         %else %if (%length(&&block&iblock)>2) %then %do;
              str='[Insert "'||&&block&iblock||'"]';
              put str;
         %end;
      %end;
      %else %if (&iblock > &totblocks) and (%length(&&block&iblock)>2) %then %do;
            str='[Insert "'||&&block&iblock||'"]';
         put str;
      %end;
   %end;
   %if (%quote(&newbmark) ne) and ((%quote(&indata) eq) or
       ((%quote(&indata) ne) and (not %index(&newbmark, %str(%'))) and
        (not %index(&newbmark, %str(%"))))) %then %do;
      put '[EditClear]';
   %end;
   %if (%quote(%upcase(&dbw)) ne %quote(T) and %quote(%upcase(&dbw)) ne %quote(TRUE)) %then %do;
      %if (%quote(%upcase(&nextdlm))= %quote(T) or %quote(%upcase(&nextdlm))=%quote(TRUE)) %then %do;
         %if (%index(%upcase(&dlm),CELL)) %then %do;
            put '[NextCell]';
         %end;
         %if (%index(&oldbmark, %str(%')) or %index(&oldbmark, %str(%")) or
             %index(&newbmark, %str(%')) or %index(&newbmark, %str(%"))) and
             (%upcase(&indata) ne _NULL_) and (%sysfunc(exist(&indata))) %then %do;
            if not lastone then do;
         %end;
         %if (%index(%upcase(&dlm),PARA) or %index(%upcase(&dlm),ENTER)) %then %do;
            %if (%index(%upcase(&dlm), OVERW)) %then %do;
               put '[CharRight 1]';
               put '[EndOfLine 1]';
            %end;
            %else %do;
               put '[InsertPara]';
            %end;
         %end;
         %else %if (%index(%upcase(&dlm),SPACE)) %then %do;
               put '[Insert " "]';
         %end;
         %else %if (%index(%upcase(&dlm),COMMA)) %then %do;
               put '[Insert ", "]';
         %end;
         %else %if (%index(%upcase(&dlm),SEMI)) %then %do;
               put '[Insert "; "]';
         %end;
         %else %if (%index(%upcase(&dlm),PERIOD)) %then %do;
               put '[Insert ". "]';
         %end;
         %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&dlm))))), %quote(ROWBELOW))) %then %do;
             put '[TableInsertRowBelow .NumRows = ""]';
         %end;
         %else %if (%index(%quote(%upcase(%sysfunc(compress(%quote(&dlm))))), %quote(ROWABOVE))) %then %do;
            put '[TableInsertRow .NumRows = ""]';
         %end;
         %else;
         %if (%index(&oldbmark, %str(%')) or %index(&oldbmark, %str(%")) or
             %index(&newbmark, %str(%')) or %index(&newbmark, %str(%"))) and
             (%upcase(&indata) ne _NULL_) and (%sysfunc(exist(&indata))) %then %do;
            end;
         %end;
      %end;
   %end;
   %if (%quote(&indata) ne) %then %do;
   run;
   %end;

%if (%index(&newbmark, %str(%')) or %index(&newbmark, %str(%"))) and (%quote(&indata) ne) %then %do;
   data _null_;
      file &wordref lrecl=2000;
      length str $2000.;
      put '[EditClear]';
      %if &newbookmark ne %then %do;
         str='[EditGoTo .Destination = "'||trim(left("&newbookmark"))||'"]';
      put str;
      %end;
      put '[CharRight 1]';
   run;
%end;
%finish:
%mend fillup;